// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//

#ifndef __GCU_CLIENT_H__
#define __GCU_CLIENT_H__

#include "gcu_common.h"

enum GCUDataBufId
{
    src0 = 0,
    src1,
    dst0,
    dst1,
    dst2,
};

enum GCURGBFormat
{
    index_8bit = 0x0,
    rgb555 = 0x1,
    rgbt5551 = 0x2,
    rgb565 = 0x3,
    rgb666 = 0x4,
    rgbt6661 = 0x5,
    rgb888 = 0x6,
    rgba6666 = 0x7,
    rgbt8881 = 0x8,
    rgba8888 = 0x9,
    rgb161616 = 0xa,
    rgba16161616 = 0xb,
};

struct GCUPixelFormat
{
    GCURGBFormat rgb_format;
    UINT32 step;
};

struct GCUColor
{
    GCUPixelFormat pixel_format;
    UINT32 color;
    UINT32 color2;
};

struct GCUDataBuf
{
    UINT32 base;
    GCUPixelFormat format;
    UINT32 stride;
};

class GCUCmdBuf
{
public:
    GCUCmdBuf(UINT alloc_size);
    ~GCUCmdBuf();
    UINT32* alloc(UINT size);
    void reset();
    UINT32* get_buf();
    UINT32 get_size();
private:
    UINT32* buf;
    UINT32* top;
    UINT buf_size;
};

class GCUContext
{
public:
    GCUContext();
    void set_sync_flag(bool flag);
    bool get_sync_flag();

    GCUDataBuf* get_data_buf(GCUDataBufId id);
    void set_data_buf(GCUDataBufId id, GCUDataBuf* buf, UINT32* cmd);
    GCUCmdBuf* get_cmd_buf();
private:
    // cache of gcu buffer info
    GCUDataBuf data_bufs[n_gcu_data_bufs];
    GCUCmdBuf cmd_buf;
    bool sync_flag;
};

class GCUClientProxy;

class GCUClient
{
public:
    GCUClient(GCUClientProxy* proxy, UINT cmd_buf_size);
    ~GCUClient();
    bool submit();
    void sync();
    bool is_sync();
    bool color_fill(GCUColor color, RECTL rect);
    bool stretch(RECTL src_rect, RECTL dst_rect);
    bool decimate(RECTL src_rect, RECTL dst_rect);
    bool rotate(UINT32 rotate,
                bool align_32bytes,
                POINTL src_p, 
                POINTL dst_p, 
                SIZEL size);
    bool raster_op(UINT32 op, 
                   POINTL src0_p, 
                   POINTL src1_p, 
                   POINTL dst_p, 
                   SIZEL size);
    bool alpha_blend(bool is_const_alpha,
                     UINT32 alpha, 
                     POINTL src0_p, 
                     POINTL src1_p, 
                     POINTL dst_p, 
                     SIZEL size);
    bool draw_line_vertical_horizontal(GCUColor color, 
                                       UINT32 dir, 
                                       POINTL start, 
                                       UINT32 length);
    bool load_buf(GCUDataBufId gcu_buf_id, GCUDataBuf* buf);
    UINT32* buffer_info(GCUDataBufId gcu_buf_id, 
                        UINT32 frame, 
                        GCUPixelFormat format,
                        UINT32 stride,
                        UINT32 step);

private:
    HANDLE sync_event;
    GCUCmdBuf cmd_buf;
    GCUContext context;
    GCUClientProxy* proxy;
};

class GCUClientProxy
{
public:
    virtual bool submit(UINT32* context_buf, UINT32 context_size, 
                        UINT32* cmd_buf, UINT32 cmd_size) = 0;
};

GCUClient* create_extern_gcu_client();

#endif